package seismosurfer.domain;

import java.util.List;
import java.util.Properties;

import seismosurfer.data.constants.Coordinates;
import seismosurfer.data.constants.ParameterNames;
import seismosurfer.data.constants.QueryNames;
import seismosurfer.data.constants.TopNCategories;
import seismosurfer.database.QuakeDAO;
import seismosurfer.servlets.util.Cache;
import seismosurfer.util.Assert;
import seismosurfer.util.Registry;
import seismosurfer.util.SeismoException;
import seismosurfer.util.UserException;

/**
 * Provides quake related operations.
 *
 */
public class Quake extends DomainObject implements Coordinates, QueryNames,
        ParameterNames, TopNCategories {
    public static final String UNKNOWN_SOURCE = "Data source is unknown.";

    public static final String UNKNOWN_INTERVAL = "Interval is unknown.";

    public static final String DEFAULT_SOURCE = "GI-NOA";

    public static final String DAY = "day";

    public static final String WEEK = "week";

    public static final String MONTH = "month";

    public static final String YEAR = "year";

    private String defaultInterval;
    
    /**
     * Creates a Quake object.
     *
     */
    public Quake() {
        Properties p = Registry.getOpenmapProperties();
        defaultInterval = p.getProperty("seismosurfer.top.interval");
        validateProperty(defaultInterval);
    }

    private void validateProperty(String prop) {
        String intervals[] = { Quake.DAY, Quake.WEEK, Quake.MONTH, Quake.YEAR };
        for (int i = 0; i < intervals.length; i++) {
            if (intervals[i].equalsIgnoreCase(prop)) {
                return;
            }
        }
        throw new SeismoException("Wrong interval property value.");
    }
    
    /**
     * Gets the default time interval which is used for the top 
     * events query in the homepage. The default interval can
     * be set in the properties file.
     * 
     * @return The default time interval for the top 
     *         events query
     */
    public String getDefaultInterval() {
        return defaultInterval;
    }
    
    /**
     * Gets a list with the data sources.
     * 
     * @return a list with the data sources
     */
    public List getSources() {
        QuakeDAO q = new QuakeDAO();
        return q.getSources();
    }
    
    /**
     * Retrieves a list with the top events (strongest quakes)
     * given the data source and the time interval.
     * 
     * @param source the String that contains the data source name
     * @param interval the time interval
     * @return a list with the top events
     * @throws UserException
     */
    public List getTopEvents(String source, String interval)
            throws UserException {

        Assert.notNull(source, "Null source.");
        Assert.notNull(interval, "Null interval.");

        fail(!Registry.getSourceNames().contains(source), SOURCE,
                UNKNOWN_SOURCE);

        if (source.equals(DEFAULT_SOURCE)) {

            if (interval.equals(DAY)) {
                return Cache.getGINOADay();
            } else if (interval.equals(WEEK)) {
                return Cache.getGINOAWeek();
            } else if (interval.equals(MONTH)) {
                return Cache.getGINOAMonth();
            } else if (interval.equals(YEAR)) {
                return Cache.getGINOAYear();
            } else {
                getNotification().put(INTERVAL, UNKNOWN_INTERVAL);
            }

        } else {

            if (interval.equals(DAY)) {
                return Cache.getNEICDay();
            } else if (interval.equals(WEEK)) {
                return Cache.getNEICWeek();
            } else if (interval.equals(MONTH)) {
                return Cache.getNEICMonth();
            } else if (interval.equals(YEAR)) {
                return Cache.getNEICYear();
            } else {
                getNotification().put(INTERVAL, UNKNOWN_INTERVAL);
            }

        }

        if (getNotification().hasErrors()) {
            throw new UserException(getNotification());
        }

        throw new UserException("Unexpected error.");
    }

}